
int gheartbeat_status = 0;

int heartbeat_get_status(void)
{
    return gheartbeat_status;
}

static void heartbeat_timer_handle(int sig, siginfo_t *info,void *context)
{
    msg_t *sigmsg = (void *)info->si_ptr;
    debug(DEBUG,__FUNCTION__,"signal %d, msg type %x mode %x arg %d\n",sig,sigmsg->type,sigmsg->mode,sigmsg->arg);
    msg_handle(sigmsg->type, sigmsg->mode, sigmsg->arg, &gstandby_prarm);
    return ;
}

int heartbeat_timer_init(void)
{
    struct sigaction act;
    timer_t timerid;
    struct sigevent sev;
    struct itimerspec its;
    sigset_t mask;

    msg_t timer_arg;
    timer_arg.type = REFRESH;
    timer_arg.mode = 0;
    timer_arg.arg = 0;

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGRTMIN;
    sev.sigev_value.sival_ptr = &timer_arg;
    if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == -1)
        debug(ERROR,__FUNCTION__,"timer_create:%s\n",strerror(errno));

    sigemptyset(&act.sa_mask);
    act.sa_sigaction = heartbeat_timer_handle;
    act.sa_flags = SA_SIGINFO;
	if (sigaction(SIGRTMIN,&act,NULL)<0)
    {
        debug(ERROR,__FUNCTION__,"sigaction:%s\n",strerror(errno));
        return -1;
    }

    its.it_value.tv_sec = 0;
    its.it_value.tv_nsec = gstandby_prarm.timer_first;
    its.it_interval.tv_sec = gstandby_prarm.timer_interval;
    its.it_interval.tv_nsec = 0;

    if (timer_settime(timerid, 0, &its, NULL) == -1)
    {
        debug(ERROR,__FUNCTION__,"timer_settime:%s\n",strerror(errno));
    }

}


int heartbeat_init(standby_t *standby_prarm)
{
    if (standby_prarm == NULL)
    {
        return -1;
    }

    if (standby_prarm->net_fd == INVALID)
    {
        standby_prarm->net_fd = udp_init(standby_prarm->net_port);
        if (standby_prarm->net_fd < 0)
        {
            standby_prarm->net_fd = INVALID;
        }
    }
    pthread_pool_work_add(t_pool, heartbeat_recv_msg, &gstandby_prarm);

	
    return 0;
}

static void heartbeat_send_msg(standby_t *standby_prarm)
{
    msg_t msg;
    msg.type = HEARTBEAT;
    msg.mode = 0;
    msg.arg = standby_prarm->role;

    if (standby_prarm->net_fd != INVALID)
    {
        udp_send(standby_prarm->net_fd, standby_prarm->net_ip, standby_prarm->net_port, &msg, sizeof(msg_t));
    }

}

static void *heartbeat_recv_msg(void *arg)
{
    standby_t *standby_prarm = arg;
    msg_t msg;

    int res = 0;
    do {
        if (standby_prarm->net_fd == INVALID)
        {
            sleep(1);
            continue;
        }

        res = udp_recv(standby_prarm->net_fd, &msg, sizeof(msg));
        if (res < 0 && errno != EAGAIN  &&res != EINTR)
        {
            debug(ERROR,__FUNCTION__,"recv: %d %d %s\n",res,errno, strerror(errno));
            udp_destroy(standby_prarm->net_fd);
            standby_prarm->net_fd = INVALID;
        }

        if (res > 0)
        {
            msg_handle(msg.type, NET_HEART_BEAT,msg.arg, standby_prarm);
        }

    } while (1);
    return NULL;
}




